﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace Converter
{
    public static class ConverterClass
    {
        #region Constants
        private static readonly string[] kopekcase = { "копеек", "копейка", "копейки", "копейки", "копейки", "копеек", "копеек", "копеек", "копеек", "копеек" };
        private static readonly string[] onescurrencycase = { "рублей", "рубль", "рубля", "рубля", "рубля", "рублей", "рублей", "рублей", "рублей", "рублей" };
        private static readonly string[] thousandscurrencycase = { "тысяч", "тысяча", "тысячи", "тысячи", "тысячи", "тысяч", "тысяч", "тысяч", "тысяч", "тысяч" };
        private static readonly string[] millionscurrencycase = { "миллионов", "миллион", "миллиона", "миллиона", "миллиона", "миллионов", "миллионов", "миллионов", "миллионов", "миллионов" };
        private static readonly string[] billionscurrencycase = { "миллиардов", "миллиард", "миллиарда", "миллиарда", "миллиарда", "миллиардов", "миллиардов", "миллиардов", "миллиардов", "миллиардов" };

        private static readonly string[] tensdigits = { "10", "11", "12", "13", "14", "15", "16", "17", "18", "19" };

        private static readonly string[] oneskopek = { "ноль", "одна", "две", "три", "четыре", "пять", "шесть", "семь", "восемь", "девять" };
        private static readonly string[] onescurrency = { "ноль", "один", "два", "три", "четыре", "пять", "шесть", "семь", "восемь", "девять" };

        private static readonly string[] tеnsAndOnes = { "десять", "одинадцать", "двенадцать", "тринадцать", "четырнадцать", "пятнадцать", "шестнадцать", "семнадцать", "восемнадцать", "девятнадцать" };
        private static readonly string[] tеns = { "", "десять", "двадцать", "тридцать", "сорок", "пятьдесят", "шестьдесят", "семдесят", "восемдесят", "девяносто" };
        private static readonly string[] hundreds = { "", "сто", "двести", "триста", "четыреста", "пятсот", "шестсот", "семсот", "восемсот", "девятсот" };
        #endregion Constants

        /// <summary>
        /// Конвертер числового представления суммы валюты в словесное
        /// </summary>
        /// <param name="value">Числовое представление суммы валюты</param>
        /// <returns>Словесное представление суммы валюты<</returns>
        public static string ConvertTo(double value)
        {
            string stringValue = value.ToString("0.00");
            int k = 0;
            string[] stringResult = new string[5];
            for (int i = stringValue.Length - 1; i >= 0; i = i - 3)
            {
                string stringFromValue = null;
                string stringcase = null;
                if (i > 0)
                {
                    stringcase = MoneyCase(k, stringValue[i - 1].ToString() + stringValue[i].ToString());
                    ///проверка того, что число находится в диапазоне 10-19
                    if (stringValue[i - 1].ToString() == "1")
                    {
                        stringFromValue = tеnsAndOnes[Convert.ToInt32(stringValue[i].ToString())];
                    }
                    else
                    {
                        stringFromValue = Ones(k, stringValue[i].ToString());
                        stringFromValue = tеns[Convert.ToInt32(stringValue[i - 1].ToString())] + " " + stringFromValue;
                    }
                }
                else
                {
                    stringcase = MoneyCase(k, stringValue[i].ToString());
                    stringFromValue = Ones(k, stringValue[i].ToString());
                }
                stringFromValue = stringFromValue + " " + stringcase;
                if ((i > 1) & (k > 0))
                {
                    stringFromValue = hundreds[Convert.ToInt32(stringValue[i - 2].ToString())] + " " + stringFromValue;
                }
                stringResult[k] = stringFromValue;
                k++;
            }
            //оформеление результата
            string stringResultValue = null;
            for (int i = k - 1; i >= 0; i--)
            {
                stringResultValue = stringResultValue + stringResult[i] + " ";
            }
            string[] split = stringResultValue.Split(new Char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            stringResultValue = "";
            foreach (string s in split)
            {
                if (stringResultValue.Length > 0)
                {
                    stringResultValue = stringResultValue + " " + s;
                }
                else
                {
                    stringResultValue = s;
                }
            }
            return stringResultValue;
        }


        /// <summary>
        /// Определение названия группы в соответствующем падеже
        /// </summary>
        /// <param name="marker">Номер группы с конца</param>
        /// <returns>Словесное представление суммы валюты<</returns>
        private static string MoneyCase(int marker, string stringdigit)
        {
            string digitcase = null;
            int iftens = 0;
            for (int i = 0; i < tensdigits.Length - 1; i++)
            {
                if (stringdigit == tensdigits[i])
                {
                    digitcase = currencyCase(marker, 0);
                    iftens++;
                    break;
                }
            }
            if (iftens == 0)
            {
                digitcase = currencyCase(marker, Convert.ToInt32(stringdigit[stringdigit.Length - 1].ToString()));
            }
            return digitcase;
        }

        /// <summary>
        /// Определение названия группы в соответствующем падеже
        /// </summary>
        /// <param name="marker">номер группы с конца</param>
        /// <param name="val">индекс числа в десятке</param>
        /// <returns>Название группы в соответствующем падеже</returns>
        private static string currencyCase(int marker, int val)
        {
            string digitcase = null;
            switch (marker)
            {
                case 0:
                    digitcase = kopekcase[val];
                    break;
                case 1:
                    digitcase = onescurrencycase[val];
                    break;
                case 2:
                    digitcase = thousandscurrencycase[val];
                    break;
                case 3:
                    digitcase = millionscurrencycase[val];
                    break;
                case 4:
                    digitcase = billionscurrencycase[val];
                    break;
            }
            return digitcase;
        }

        /// <summary>
        /// Определение чмсла до 10
        /// </summary>
        /// <param name="marker">Номер группы с конца</param>
        /// <param name="digit">Число до 10</param>
        /// <returns>Словесное представление числа до 10</returns>
        private static string Ones(int marker, string digit)
        {
            string digitstring = null;
            if ((marker == 0) | (marker == 2))
            {
                digitstring = oneskopek[Convert.ToInt32(digit.ToString())];
            }
            if ((marker == 1) | (marker == 3) | (marker == 4))
            {
                digitstring = onescurrency[Convert.ToInt32(digit.ToString())];
            }
            return digitstring;
        }
    }
}
